EL presente laboratorio expone el análisis de los árboles de decisión. Se presenta:
Los siguientes enlaces son referentes al análisis de texto descriptivo:
https://www.tidytextmining.com/ https://rpubs.com/jboscomendoza/analisis_sentimientos_lexico_afinn
https://rpubs.com/jboscomendoza/mineria-de-textos-con-r
https://rpubs.com/jboscomendoza/coheed_and_cambria
https://rpubs.com/pjmurphy/265713 https://medium.com/@actsusanli/text-mining-is-fun-with-r-35e537b12002 https://rpubs.com/Joaquin_AR/334526 https://blogs.solidq.com/es/advanced-analytics/introduccion-al-text-mining-con-r-parte-i/
https://rpubs.com/cbpuschmann/textmining
https://rpubs.com/cruzcancel/238997 https://rpubs.com/novrisuhermi/twitter_text_mining_2 http://www.rpubs.com/peg/136839 https://rpubs.com/HAVB/tangos
Estos son los datos que se utilizarán en el laboratorio
El propósito del siguiente conjunto de datos titanic es predecir que personas son más propensas a sobrevivir la colisión con el iceberg. El conjunto de datos contiene 13 variables y 1309 observaciones.
## 'data.frame': 1309 obs. of 13 variables:
## $ X : int 1 2 3 4 5 6 7 8 9 10 ...
## $ pclass : int 1 1 1 1 1 1 1 1 1 1 ...
## $ survived : int 1 1 0 0 0 1 1 0 1 0 ...
## $ name : Factor w/ 1307 levels "Abbing, Mr. Anthony",..: 22 24 25 26 27 31 46 47 51 55 ...
## $ sex : Factor w/ 2 levels "female","male": 1 2 1 2 1 2 1 2 1 2 ...
## $ age : num 29 0.917 2 30 25 ...
## $ sibsp : int 0 1 1 1 1 0 1 0 2 0 ...
## $ parch : int 0 2 2 2 2 0 0 0 0 0 ...
## $ ticket : Factor w/ 929 levels "110152","110413",..: 188 50 50 50 50 125 93 16 77 826 ...
## $ fare : num 211 152 152 152 152 ...
## $ cabin : Factor w/ 187 levels "","A10","A11",..: 45 81 81 81 81 151 147 17 63 1 ...
## $ embarked : Factor w/ 4 levels "","C","Q","S": 4 4 4 4 4 4 4 4 4 2 ...
## $ home.dest: Factor w/ 370 levels "","?Havana, Cuba",..: 310 232 232 232 232 238 163 25 23 230 ...
Los datos no están ordenados aleatoriamente sino secuencialmente de acuerdo a la variable categórica de interés. Esto es un problema importante y se debe corregir antes de dividir los datos en entrenamiento y test. Para desordenar la lista de observaciones, se puede usar la función sample()
## [1] 57 774 796 1044 681 920
Hacemos una limpieza de los datos…
Existen valores NA’s, por lo tanto deben ser eliminados. Prescindir de variables innecesarias Crear-convertir variables a tipo factor de ser necesario (e.g., pclass y survived)
## Observations: 1,045
## Variables: 9
## $ X <int> 57, 774, 920, 430, 1012, 476, 653, 1295, 79, 517, 312...
## $ pclass <fct> Upper, Lower, Lower, Middle, Lower, Middle, Lower, Lo...
## $ survived <fct> Yes, No, No, No, No, No, No, No, Yes, No, Yes, No, No...
## $ sex <fct> male, male, male, male, female, female, male, male, f...
## $ age <dbl> 36.0, 42.0, 18.5, 44.0, 19.0, 26.0, 23.0, 28.5, 64.0,...
## $ sibsp <int> 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0,...
## $ parch <int> 2, 0, 0, 0, 0, 1, 0, 0, 2, 2, 1, 0, 0, 0, 0, 1, 0, 0,...
## $ fare <dbl> 120.0000, 8.6625, 7.2292, 13.0000, 16.1000, 26.0000, ...
## $ embarked <fct> S, S, C, S, S, S, S, S, C, S, S, S, S, S, S, S, S, S,...
Los datos que analizamos son datos de vinos blancos de Portugal. El conjunto de datos se puede acceder en Repositorio de Datos de Aprendizaje Automático de UCI http://archive.ics.uci.edu/ml
url <-"http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv"
wine <- read.table(file=url, header = T, sep=";")
knitr::kable(head(wine),caption = "Resumen de datos")
| fixed.acidity | volatile.acidity | citric.acid | residual.sugar | chlorides | free.sulfur.dioxide | total.sulfur.dioxide | density | pH | sulphates | alcohol | quality |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 7.0 | 0.27 | 0.36 | 20.7 | 0.045 | 45 | 170 | 1.0010 | 3.00 | 0.45 | 8.8 | 6 |
| 6.3 | 0.30 | 0.34 | 1.6 | 0.049 | 14 | 132 | 0.9940 | 3.30 | 0.49 | 9.5 | 6 |
| 8.1 | 0.28 | 0.40 | 6.9 | 0.050 | 30 | 97 | 0.9951 | 3.26 | 0.44 | 10.1 | 6 |
| 7.2 | 0.23 | 0.32 | 8.5 | 0.058 | 47 | 186 | 0.9956 | 3.19 | 0.40 | 9.9 | 6 |
| 7.2 | 0.23 | 0.32 | 8.5 | 0.058 | 47 | 186 | 0.9956 | 3.19 | 0.40 | 9.9 | 6 |
| 8.1 | 0.28 | 0.40 | 6.9 | 0.050 | 30 | 97 | 0.9951 | 3.26 | 0.44 | 10.1 | 6 |
str(wine)
## 'data.frame': 4898 obs. of 12 variables:
## $ fixed.acidity : num 7 6.3 8.1 7.2 7.2 8.1 6.2 7 6.3 8.1 ...
## $ volatile.acidity : num 0.27 0.3 0.28 0.23 0.23 0.28 0.32 0.27 0.3 0.22 ...
## $ citric.acid : num 0.36 0.34 0.4 0.32 0.32 0.4 0.16 0.36 0.34 0.43 ...
## $ residual.sugar : num 20.7 1.6 6.9 8.5 8.5 6.9 7 20.7 1.6 1.5 ...
## $ chlorides : num 0.045 0.049 0.05 0.058 0.058 0.05 0.045 0.045 0.049 0.044 ...
## $ free.sulfur.dioxide : num 45 14 30 47 47 30 30 45 14 28 ...
## $ total.sulfur.dioxide: num 170 132 97 186 186 97 136 170 132 129 ...
## $ density : num 1.001 0.994 0.995 0.996 0.996 ...
## $ pH : num 3 3.3 3.26 3.19 3.19 3.26 3.18 3 3.3 3.22 ...
## $ sulphates : num 0.45 0.49 0.44 0.4 0.4 0.44 0.47 0.45 0.49 0.45 ...
## $ alcohol : num 8.8 9.5 10.1 9.9 9.9 10.1 9.6 8.8 9.5 11 ...
## $ quality : int 6 6 6 6 6 6 6 6 6 6 ...
Existen varios algoritmos implementados en R para llevar a cabo los árboles de decisión: ID3, CART, C4.5 C5.0, CHAID.
Es importante saber que existen variadas implementaciones (librerías) de árboles de decisión en R como por ejemplo: rpart, tree, party, ctree, etc. Algunas se diferencias en las heurísticas utilizadas para el proceso de poda del árbol y otras manejan un componente probabilísto internamente.
Un ejemplo del esquema general para implementación.
# x <- cbind(x_train,y_train)
# fit <- rpart(y_train ~ ., data = x,method="class")
# summary(fit)
# predicted= predict(fit,x_test)
https://www.rdocumentation.org/packages/rpart/versions/4.1-15/topics/rpart
# rpart(formula, data, weights, subset, na.action = na.rpart, method,
# model = FALSE, x = FALSE, y = TRUE, parms, control, cost, …)
https://www.rdocumentation.org/packages/tree/versions/1.0-40
# tree(formula, data, weights, subset,
# na.action = na.pass, control = tree.control(nobs, ...),
# method = "recursive.partition",
# split = c("deviance", "gini"),
# model = FALSE, x = FALSE, y = TRUE, wts = TRUE, ...)
https://www.rdocumentation.org/packages/partykit/versions/1.2-4/topics/party
# party(node, data, fitted = NULL, terms = NULL, names = NULL,
# info = NULL)
https://www.rdocumentation.org/packages/partykit/versions/1.2-4/topics/ctree
# ctree(formula, data, subset, weights, na.action = na.pass, offset, cluster,
# control = ctree_control(…), ytrafo = NULL,
# converged = NULL, scores = NULL, doFit = TRUE, …)
En los análisis, realizar análisis descriptivos para la variable dependiente Análisis descriptivos para las variables dependientes
Antes de entrenar el modelo vamos a dividir el conjunto de datos en entrenamiento y test. La práctica común es 80-20. Crearemos una función con este propósito.
## pclass survived sex age sibsp parch fare embarked
## 1 Lower No male 17 0 0 7.8958 S
## 2 Middle No female 22 0 0 21.0000 S
## 3 Lower No male 22 0 0 9.3500 S
## 4 Middle Yes male 2 1 1 23.0000 S
## 5 Lower No male 18 0 0 7.7500 S
## 6 Upper Yes female 26 1 0 136.7792 C
## [1] 836 8
## [1] 209 8
Conjunto de entrenamiento = 1046 filas (instancias) Conjunto de test = 262 filas (instancias)
Ahora verificamos el proceso de aleatoriedad a través de las funciones prop.table() combinada con table()
prop.table(table(data_train$survived))
##
## No Yes
## 0.5980861 0.4019139
prop.table(table(data_test$survived))
##
## No Yes
## 0.5645933 0.4354067
El comando para generar un modelo de árbol de decisión, usando la librería rpart lleva el mismo nombre.
Cada nodo muestra
La clase predecida (died o survived), La probabilidad predecida de survival, El porcentaje de observaciones en el nodo.
Ahora probemos con las opciones 1 y 9.
Opción 1
Opción 9
Los árboles de decisión requieren muy poca preparación de datos. Particularmente, no requieren escalamiento de atributos o centrado.
Por defecto, rpart() use la medida de Gini para la división de los nodos.
El modelo ha sido entrenado y ahora puede ser usado para predecir nuevas instancias en el conjunto de datos de test. Para esto se usa la función predict().
#Arguments:
#- fitted_model: This is the object stored after model estimation.
#- df: Data frame used to make the prediction
#- type: Type of prediction
# - 'class': for classification
# - 'prob': to compute the probability of each class
# - 'vector': Predict the mean response at the node level
Contabilizar la coincidencia entre las observaciones de test y los valores predecidos (matriz de confusión).
## predict_unseen
## No Yes
## No 107 11
## Yes 33 58
¿Que podemos concluir de esto?
A partir de la matriz de confusión es posible calcular un medida de rendimiento del modelo. La matriz de confusión es utilizada en casos de clasificación.
## [1] "Precisión de la prueba 0.789473684210526"
Para incluir restricciones definidas por el usuario respecto a cómo elaborar el árbol de decisión se puede utilizar el comando rpart.control() de la librería rpart.
#rpart.control(minsplit = 20, minbucket = round(minsplit/3), maxdepth = 30)
#Arguments:
#-minsplit: Set the minimum number of observations in the node before the algorithm perform a split
#-minbucket: Set the minimum number of observations in the final node i.e. the leaf
#-maxdepth: Set the maximum depth of any node of the final tree. The root node is treated a depth 0
Vamos a modificar el ejemplo anterior. Para ello vamos a constuir una función que encapsule el cáculo de la precisión del modelo.
Ahora, vamos a ajustar los parámetros para intentar mejor el rendimiento del modelo sobre los valores por defecto. La precisión que obtuvimos previamente fue de 0.78.
## [1] 0.7894737
En efecto hemos mejorado ligeramente la estimación de 0.78 a 0.79. Como habíamos revisado anteriormente, lo ideal sería aplicar un proceso de validación cruzada para ajustar correctamente y encontrar así la mejor combinación.
Queremos predecir la calidad del vino, Quality según otras características del mismo:
acidity sugar content chlorides sulfur alcohol pH density
Explorando los datos
Parece que Quality sigue una distribución más o menos Normal.
Veamos las densidades
No es necesario el procesamiento previo de datos para emplear un modelo de árbol de decisión. Para los datos de entrenamiento (training) y prueba (test) vamos a tomar una muestra al azar con una proporción del 75% y del 25% respectivamente.
## [1] 3750
## n= 3750
##
## node), split, n, deviance, yval
## * denotes terminal node
##
## 1) root 3750 2920.95600 5.881067
## 2) alcohol< 10.85 2351 1394.32200 5.603998
## 4) volatile.acidity>=0.2375 1483 718.65410 5.395819
## 8) free.sulfur.dioxide< 17.5 204 100.87750 5.024510 *
## 9) free.sulfur.dioxide>=17.5 1279 585.16500 5.455043
## 18) alcohol< 10.01667 951 359.84230 5.362776 *
## 19) alcohol>=10.01667 328 193.75300 5.722561 *
## 5) volatile.acidity< 0.2375 868 501.58870 5.959677 *
## 3) alcohol>=10.85 1399 1042.86200 6.346676
## 6) free.sulfur.dioxide< 10.5 73 77.75342 5.315068 *
## 7) free.sulfur.dioxide>=10.5 1326 883.14400 6.403469
## 14) alcohol< 11.775 660 422.58180 6.218182 *
## 15) alcohol>=11.775 666 415.44890 6.587087 *
Veamos el árbol
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 5.025 5.363 5.960 5.882 6.218 6.587
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 3.000 5.000 6.000 5.868 6.000 8.000
Otra forma de analizar el rendimiento del modelo es considerar cómo de diferente, en promedio, ha caído la predicción del valor real: Error absoluto medio (MAE).
## [1] 0.5987078
Un Error Absoluto Medio del 59% es aceptable.